import Vue from 'vue'
import './FilterGroup.css'

Vue.component('filters-group', {
  props: {
    filterGroup: {},
    flag: false,
    draggable: true
  },
  data () {
    return {
      dragStop: false,
      dragLocation: '',
      dragIndex: 0,
      dragItem: {}
    }
  },
  render: function (createElement) {
    console.log('渲染页面 Dom => ', this.filterGroup)
    /* 判断filters有没有值，是为了在filters没有值的时候给第一个(i===0)children的上面加个空白的div，便于拖拽 */
    return this.renderFilterGroup(this.filterGroup, this.filterGroup.filters.length === 0)
  },
  methods: {
    /* ******************渲染页面********************************/
    renderFilterGroupBottomDiv (location) {
      const h = this.$createElement
      return h('div', {
        class: 'filterGroupBottomDiv',
        style: {height: '10px'},
        on: {
          drop: e => self.onDropDiv(location, e),
          dragenter: e => self.onDragEnter(e),
          dragleave: e => self.onDragLeave(e),
          dragover: e => self.onDragOver(e)
        }
      })
    },
    renderFilterGroupTopDiv (location) {
      const h = this.$createElement
      return h('div', {
        class: 'filterGroupTopDiv',
        style: {height: '10px'},
        on: {
          drop: e => self.onDropDiv(location, e),
          dragenter: e => self.onDragEnter(e),
          dragleave: e => self.onDragLeave(e),
          dragover: e => self.onDragOver(e)
        }
      })
    },
    renderFilterDiv (filter, i, location, filterGroup) {
      if (!filter) return null
      const self = this
      const h = this.$createElement
      let innerEls = []
      if (i === 0) {
        innerEls.push(h('div', {
          style: {height: '10px'},
          on: {
            drop: (e) => self.onDropDiv(location, e),
            dragenter: (e) => self.onDragEnter(e),
            dragleave: (e) => self.onDragLeave(e),
            dragover: (e) => self.onDragOver(e)
          }
        }))
      }

      innerEls.push(h('div', {
        style: {cursor: 'move', userSelect: 'none'},
        domProps: {draggable: this.draggable ? 'true' : 'false'},
        on: {
          dragstart: e => self.dragStart(filter, i, location, filterGroup),
          drop: e => self.onDrop(filter, i, location, e),
          dragenter: e => self.onDragEnter(e),
          dragleave: e => self.onDragLeave(e),
          dragover: e => self.onDragOver(e)
        }
      }, filter.dimName))

      innerEls.push(h('div', {
        style: {height: '10px'},
        on: {
          drop: e => self.onDropDiv(location, e),
          dragenter: e => self.onDragEnter(e),
          dragleave: e => self.onDragLeave(e),
          dragover: e => self.onDragOver(e)
        }
      }))
      return h('div', {}, innerEls)
    },
    renderFilterGroupItems (filterGroup, flag) {
      const self = this
      const h = this.$createElement
      let innerEls = []
      filterGroup.filters.map((f, i) =>
        innerEls.push(self.renderFilterDiv(f, i, filterGroup.location, filterGroup))
      )

      if (flag) {
        innerEls.push(this.renderFilterGroupTopDiv(filterGroup.location))
      }

      if (filterGroup.children && filterGroup.children.length) {
        filterGroup.children.map((f, i) =>
          innerEls.push(this.renderFilterGroup(f))
        )
      }

      if (filterGroup.children && filterGroup.children.length > 0) {
        innerEls.push(this.renderFilterGroupBottomDiv(filterGroup.location))
      }

      return h('div', {class: 'filterGroupItems'}, innerEls)
    },
    renderFilterGroupBrace () {
      const h = this.$createElement
      return h('div', {class: 'filterGroupBrace'})
    },
    renderFilterGroupList (filterGroup, flag) {
      const h = this.$createElement
      return h('div', {class: 'filterGroupList'}, [
        this.renderFilterGroupBrace(),
        this.renderFilterGroupItems(filterGroup, flag)
      ])
    },
    renderSymbolDiv (filterGroup) {
      const h = this.$createElement
      return h('div', {
        class: 'symbol',
        on: {
          click: () => this.changeSymbol(filterGroup)
        }
      }, filterGroup.symbol)
    },
    renderFilterGroup (filterGroup, flag) {
      console.log('渲染 filter group => ', filterGroup)
      const h = this.$createElement
      return h('div', {class: 'filterGroup'}, [
        this.renderSymbolDiv(filterGroup),
        this.renderFilterGroupList(filterGroup, flag)
      ])
    },
    /* ******************渲染页面完成*******************************/
    dragStart (filter, index, location, filterGroup) {
      console.log('on drag start')
      if (filterGroup.filters.length < 2 && filterGroup.children.length < 2) {
        this.dragStop = true
      }
      this.dragItem = filter
      this.dragLocation = location
      this.dragIndex = index
    },
    changeSymbol (filterGroup) {
      let tempFilterGroupStr = JSON.stringify(this.filterGroup)
      let tempFilterGroup = JSON.parse(tempFilterGroupStr)

      let location = filterGroup.location
      if (location.length === 1) {
        if (tempFilterGroup.symbol === 'and') {
          tempFilterGroup.symbol = 'or'
        } else {
          tempFilterGroup.symbol = 'and'
        }
      } else {
        let temp = tempFilterGroup.children
        for (let i = 1; i < location.length; i++) {
          if (i === location.length - 1) {
            temp = temp[location[i]]
          } else {
            temp = temp[location[i]].children
          }
        }
        if (temp.symbol === 'and') {
          temp.symbol = 'or'
        } else {
          temp.symbol = 'and'
        }
      }

      this.$emit('update:filterGroup', tempFilterGroup)
    },
    onDrop (filter, index, location, e) {
      console.log('on drop => filter: ', filter, ' index: ', index, 'location: ', location, 'e: ', e)
      e.target.style.backgroundColor = ''
      // event.preventDefault();
      if (this.dragStop) {
        this.dragStop = false
        return
      }
      let tempFilterGroupStr = JSON.stringify(this.filterGroup)
      let tempFilterGroup = JSON.parse(tempFilterGroupStr)
      if (this.dragItem.dimName === filter.dimName) {
        return
      }

      // 如果是最外层
      if (location.length === 1) {
        if (this.dragLocation === location && tempFilterGroup.filters.length <= 2 && tempFilterGroup.children.length === 0) {
          return
        }
        let tempLocation = '1' + tempFilterGroup.children.length
        let temp = {symbol: 'and', filters: [], children: [], location: tempLocation}
        temp.filters.push(filter)
        temp.filters.push(this.dragItem)
        tempFilterGroup.children.push(temp)
        // 删除drop的数据
        console.log('temp filter group => ', tempFilterGroup)
        console.log('temp filter group delete => ', index)
        tempFilterGroup.filters.splice(index, 1)
      } else {
        let temp = tempFilterGroup.children
        for (let i = 1; i < location.length; i++) {
          if (i === location.length - 1) {
            temp = temp[location[i]]
          } else {
            temp = temp[location[i]].children
          }
        }
        if (this.dragLocation === location && temp.filters.length <= 2 && temp.children.length === 0) {
          return
        }
        let tempLocation = location + temp.children.length
        let temp1 = {symbol: 'and', filters: [], children: [], location: tempLocation}
        temp1.filters.push(filter)
        temp1.filters.push(this.dragItem)
        temp.children.push(temp1)

        // 删除drop的数据
        console.log('temp => ', temp)
        console.log('temp delete => ', index)
        temp.filters.splice(index, 1)
      }

      // 表示drag和drop的数据都在同一个filters中，且drop的数据在前，那么删除drop后，drag的位置就往前提了一位
      let dragIndex = this.dragIndex
      if (this.dragLocation === location && index < this.dragIndex) {
        dragIndex = dragIndex - 1
      }
      // 删除drag的数据
      console.log('temp filter group => ', tempFilterGroup)
      if (this.dragLocation.length === 1) {
        console.log('temp filter group delete => ', dragIndex)
        tempFilterGroup.filters.splice(dragIndex, 1)
      } else {
        let temp = tempFilterGroup.children
        let tempChildren = tempFilterGroup.children
        let tempFilters = tempFilterGroup.filters // tempFilters表示被drag元素的上一层的filters
        for (let i = 1; i < this.dragLocation.length; i++) {
          if (i === this.dragLocation.length - 1) {
            tempChildren = temp
            temp = temp[this.dragLocation[i]]
          } else {
            if (i === this.dragLocation.length - 2) {
              tempFilters = temp[this.dragLocation[i]].filters
            }
            temp = temp[this.dragLocation[i]].children
          }
        }
        console.log('temp => ', temp)
        console.log('filters delete index => ', dragIndex)
        temp.filters.splice(dragIndex, 1)

        if (temp.filters.length === 1 && temp.children.length === 0) {
          // 将最后剩下的一个放到上一层的filters中
          tempFilters.push(temp.filters[0])
          // 一个filter没有必要打个括号，将整个对象从children数组中剔除
          console.log('temp children => ', tempChildren)
          console.log('temp children delete index => ', this.dragLocation[this.dragLocation.length - 1])
          tempChildren.splice(this.dragLocation[this.dragLocation.length - 1], 1)
          // children中删除一个后，它后面的location的值要跟着变化
          for (let n = this.dragLocation[this.dragLocation.length - 1]; n < tempChildren.length; n++) {
            tempChildren[n].location = tempChildren[n].location.substring(0, tempChildren[n].location.length - 1) + n
          }
        }
      }

      console.log('temp filter group in drop => ', tempFilterGroup)
      this.$emit('update:filterGroup', tempFilterGroup)
    },
    onDropDiv (location, e) {
      console.log('on drop div')
      e.target.style.backgroundColor = ''
      if (this.dragStop) {
        this.dragStop = false
        return
      }
      let tempFilterGroupStr = JSON.stringify(this.filterGroup)
      let tempFilterGroup = JSON.parse(tempFilterGroupStr)
      console.log('temp filter group => ', tempFilterGroup)
      if (location.length === 1) {
        tempFilterGroup.filters.push(this.dragItem)
      } else {
        let temp = tempFilterGroup.children
        for (let i = 1; i < location.length; i++) {
          if (i === location.length - 1) {
            temp = temp[location[i]]
          } else {
            temp = temp[location[i]] && temp[location[i]].children ? temp[location[i]].children : []
          }
        }
        temp.filters.push(this.dragItem)
      }

      // 删除被drag的数据
      console.log('temp filter group => ', tempFilterGroup)
      if (this.dragLocation.length === 1) {
        tempFilterGroup.filters.splice(this.dragIndex, 1)
      } else {
        let temp = tempFilterGroup.children
        let tempChildren = tempFilterGroup.children
        let tempFilters = tempFilterGroup.filters // tempFilters表示被drag元素的上一层的filters
        for (let i = 1; i < this.dragLocation.length; i++) {
          if (i === this.dragLocation.length - 1) {
            tempChildren = temp
            temp = temp[this.dragLocation[i]]
          } else {
            if (i === this.dragLocation.length - 2) {
              tempFilters = temp[this.dragLocation[i]].filters
            }
            temp = temp[this.dragLocation[i]].children
          }
        }
        console.log('temp => ', temp)
        temp.filters.splice(this.dragIndex, 1)
        if (temp.filters.length === 1 && temp.children.length === 0) {
          // 将最后剩下的一个放到上一层的filters中
          tempFilters.push(temp.filters[0])
          // 一个filter没有必要打个括号，将整个对象从children数组中剔除
          console.log('temp children => ', tempChildren)
          tempChildren.splice(this.dragLocation[this.dragLocation.length - 1], 1)
          // children中删除一个后，它后面的location的值要跟着变化
          for (let n = this.dragLocation[this.dragLocation.length - 1]; n < tempChildren.length; n++) {
            tempChildren[n].location = tempChildren[n].location.substring(0, tempChildren[n].location.length - 1) + n
          }
        }
      }

      this.$emit('update:filterGroup', tempFilterGroup)
    },
    onDragOver (event) {
      console.log('on drag over')
      event.preventDefault()
      event.target.style.backgroundColor = '#a0c5e8'
    },
    onDragEnter (e) {
      console.log('on drag enter')
      // e.target.style.backgroundColor = "#a0c5e8"
    },
    onDragLeave (e) {
      console.log('on drag leave')
      e.target.style.backgroundColor = ''
    }
  }
})
